﻿using Pe.Petecos.Comercial.Aplicacion.Core.Base;
using Pe.Petecos.Comercial.Aplicacion.Core.ServiceContract;
using Pe.Petecos.Comercial.Aplicacion.Service.Base;
using Pe.Petecos.Comercial.Aplicacion.TransferObject.Ventas;
using Pe.Petecos.Comercial.Cross.Core.Constantes;
using Pe.Petecos.Comercial.Cross.Core.Exception;
using Pe.Petecos.Comercial.Cross.Document.Excel;
using Pe.Petecos.Comercial.Infraestructura.Core.Contract.Ventas;
using Pe.Petecos.Comercial.Infraestructura.Model.Ventas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Reporting.WebForms;
using Pe.Petecos.Comercial.Aplicacion.TransferObject.Correo;
using System.IO;
using System.Web;

namespace Pe.Petecos.Comercial.Aplicacion.Service.Implements
{
    public class VentasService : GenericService, IVentasService
    {
        public ICorreoService correoService { get; set; }
        public IGeneralService generalService { get; set; }

        public IEventoRepository eventoRepository { get; set; }
        public IProyectoRepository proyectoRepository { get; set; }
        public IOrdenCompraRepository ordenCompraRepository { get; set; }
        public IComprobantePagoRepository comprobantePagoRepository { get; set; }
        public IGastoPersonalProyectoRepository gastoPersonalProyectoRepository { get; set; }

        #region Evento
        public ProcessResult<List<DataEvento>> BuscarEvento(FiltroEvento filtro)
        {
            ProcessResult<List<DataEvento>> resultado = new ProcessResult<List<DataEvento>>();
            try
            {
                var fechaInicio = Formato.StringFormatDatetime(filtro.FechaInicio);
                var fechaFin = Formato.StringFormatDatetime(filtro.FechaFin);

                var listado = eventoRepository.Buscar(codigoCliente: filtro.CodigoCliente, codigoEstado: filtro.CodigoEstado, nombreCliente: filtro.NombreCliente, nombreEvento: filtro.NombreEvento, fechaInicio: fechaInicio, fechaFin: fechaFin);

                resultado.Result = listado.Select(x => new DataEvento
                {
                    CodigoEvento = x.CodigoEvento,
                    NombreEvento = x.NombreEvento,
                    CodigoTipoEvento = x.CodigoTipoEvento,
                    FechaEvento = Formato.DatetimeFormatString(x.FechaEvento),
                    LugarEvento = x.LugarEvento,
                    NombreEncargado = x.NombreEncargado,
                    Objetivo = x.Objetivo,
                    Observaciones = x.Observaciones,
                    EsPresupuesto = x.EsPresupuesto,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoTotal = x.MontoTotal,
                    CodigoMoneda = x.CodigoMoneda,
                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    CodigoCliente = x.CodigoCliente,
                    NombreCliente = x.NombreCliente,
                    Telefono = x.Telefono,
                    NumeroDocumento = x.NumeroDocumento,
                    CorreoElectronico = x.CorreoElectronico,

                    DocumentoContacto = x.DocumentoContacto,
                    NombreContacto = x.NombreContacto,
                    CorreoElectronicoContacto = x.CorreoElectronicoContacto,
                    TelefonoContacto = x.TelefonoContacto,

                    NombreEstado = x.NombreEstado,
                    NombreTipoEvento = x.NombreTipoEvento
                }).ToList();
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataEvento> ObtenerEvento(int codigo)
        {
            ProcessResult<DataEvento> resultado = new ProcessResult<DataEvento>();
            try
            {
                var listado = eventoRepository.Buscar(codigoEvento: codigo);
                var evento = listado.Select(x => new DataEvento
                {
                    CodigoEvento = x.CodigoEvento,
                    NombreEvento = x.NombreEvento,
                    CodigoTipoEvento = x.CodigoTipoEvento,
                    FechaEvento = Formato.DatetimeFormatString(x.FechaEvento),
                    LugarEvento = x.LugarEvento,
                    NombreEncargado = x.NombreEncargado,
                    Objetivo = x.Objetivo,
                    Observaciones = x.Observaciones,
                    EsPresupuesto = x.EsPresupuesto,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoTotal = x.MontoTotal,
                    CodigoMoneda = x.CodigoMoneda,
                    NombreMoneda = x.NombreMoneda,
                    CodigoEstado = x.CodigoEstado,

                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaModificacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    CodigoCliente = x.CodigoCliente,
                    NombreCliente = x.NombreCliente,
                    Telefono = x.Telefono,
                    NumeroDocumento = x.NumeroDocumento,
                    CorreoElectronico = x.CorreoElectronico,

                    DocumentoContacto = x.DocumentoContacto,
                    NombreContacto = x.NombreContacto,
                    CorreoElectronicoContacto = x.CorreoElectronicoContacto,
                    TelefonoContacto = x.TelefonoContacto,

                    NombreEstado = x.NombreEstado,
                    NombreTipoEvento = x.NombreTipoEvento,

                    CodigoUsuario = x.CodigoUsuario,
                    NombreUsuarioCompleto = x.NombreUsuarioCompleto,
                    EmailUsuario = x.EmailUsuario

                }).FirstOrDefault();

                if (evento != null)
                {
                    evento.ListaEventoDetalle = eventoRepository.BuscarDetalle(evento.CodigoEvento).Select(x => new DataEventoDetalle
                    {
                        CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                        CodigoArticulo = x.CodigoArticulo,
                        CodigoProveedor = x.CodigoProveedor,
                        NombreGrupo = x.NombreGrupo,
                        NombreArticulo = x.NombreArticulo,
                        NombreProveedor = x.NombreProveedor,
                        Cantidad = x.Cantidad,
                        PrecioUnitario = x.PrecioArticulo,
                        MontoTotal = x.MontoTotal
                    }).ToList();
                }

                resultado.Result = evento;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataEvento> RegistrarEvento(DataEvento evento)
        {
            ProcessResult<DataEvento> resultado = new ProcessResult<DataEvento>();
            try
            {
                var eventoRegistro = new EventoEntity();
                eventoRegistro.CodigoEvento = evento.CodigoEvento;
                eventoRegistro.CodigoMoneda = evento.CodigoMoneda;
                eventoRegistro.CodigoTipoEvento = evento.CodigoTipoEvento;
                eventoRegistro.CodigoCliente = evento.CodigoCliente;
                eventoRegistro.Nombre = evento.NombreEvento;
                eventoRegistro.Fecha = Formato.StringFormatDatetime(evento.FechaEvento).Value;
                eventoRegistro.Lugar = evento.LugarEvento; //(evento.LugarEvento == null || evento.LugarEvento == "") ? "Ninguno" : evento.LugarEvento;
                eventoRegistro.NombreEncargado = evento.NombreEncargado; //(evento.NombreEncargado == null || evento.NombreEncargado == "") ? "3" : evento.NombreEncargado;
                eventoRegistro.Objetivo = evento.Objetivo; //(evento.Objetivo == null || evento.Objetivo == "") ? "Ninguno" : evento.Objetivo;
                eventoRegistro.Observaciones = evento.Observaciones; //(evento.Observaciones == null || evento.Observaciones == "") ? "Ninguna" : evento.Observaciones;

                eventoRegistro.DocumentoContacto = evento.DocumentoContacto;
                eventoRegistro.NombreContacto = evento.NombreContacto;
                eventoRegistro.CorreoElectronicoContacto = evento.CorreoElectronicoContacto;
                eventoRegistro.TelefonoContacto = evento.TelefonoContacto;


                eventoRegistro.UsuarioCreacion = evento.UsuarioCreacion;
                eventoRegistro.UsuarioModificacion = evento.UsuarioModificacion;

                eventoRegistro.ListaEventoDetalle = evento.ListaEventoDetalle.Select(x => new EventoDetalleEntity
                {
                    CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                    NombreGrupo = x.NombreGrupo,
                    PrecioArticulo = x.PrecioUnitario,
                    Cantidad = x.Cantidad,
                    MontoTotal = x.PrecioUnitario * x.Cantidad
                }).ToList();

                eventoRegistro.MontoSubTotal = eventoRegistro.ListaEventoDetalle.Sum(x => x.MontoTotal);
                eventoRegistro.MontoIgv = eventoRegistro.MontoSubTotal * DatosConstantes.Monto.Igv;
                eventoRegistro.MontoTotal = eventoRegistro.MontoSubTotal + eventoRegistro.MontoIgv;

                if (evento.CodigoEvento == 0)
                {
                    eventoRegistro.CodigoEstado = DatosConstantes.EstadoEvento.Registrado;
                    eventoRegistro.EsPresupuesto = true;
                    evento.CodigoEvento = eventoRepository.Insertar(eventoRegistro);
                }
                else
                {
                    eventoRepository.Modificar(eventoRegistro);
                }

                resultado.Result = ObtenerEvento(evento.CodigoEvento).Result;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<int>> ModificarEstadoEvento(List<int> codigos, string estado, string usuario)
        {
            ProcessResult<List<int>> resultado = new ProcessResult<List<int>>();
            try
            {
                var listado = eventoRepository.ModificarEstado(codigos, estado, usuario);
                if (DatosConstantes.EstadoEvento.PreAprobado == estado || DatosConstantes.EstadoEvento.Aprobado == estado || DatosConstantes.EstadoEvento.Aceptado == estado)
                {
                    foreach (var item in codigos)
                    {
                        EnviarEvento(item, estado);
                    }
                }
                resultado.Result = codigos;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataEvento> CopiarEvento(int codigo, string usuario)
        {

            ProcessResult<DataEvento> resultado = new ProcessResult<DataEvento>();
            try
            {

                resultado = ObtenerEvento(codigo);
                resultado.Result.CodigoEvento = 0;
                resultado.Result.UsuarioCreacion = usuario;

                resultado = RegistrarEvento(resultado.Result);

            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<string> EnviarEvento(int codigo, string estado)
        {
            ProcessResult<string> resultado = new ProcessResult<string>();
            bool adjunto = false;
            DataEmail dataEmail = new DataEmail();
            var obtenerEvento = ObtenerEvento(codigo).Result;
            dataEmail.Para.Add(new DataDirecciones() { Email = obtenerEvento.EmailUsuario, NombreCompleto = obtenerEvento.NombreUsuarioCompleto });

            var emailAdministradores = generalService.BuscarOpcion(DatosConstantes.Parametro.EmailAdministradores).Result;
            foreach (var item in emailAdministradores)
            {
                dataEmail.ConCopia.Add(new DataDirecciones() { Email = item.Nombre, NombreCompleto = item.Nombre });
            }

            if (DatosConstantes.EstadoEvento.PreAprobado == estado)
            {
                dataEmail.Asunto = string.Concat("Pre Aprobación Presupuesto ", obtenerEvento.CodigoEvento);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlPreAprobadoPresupuesto.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                email = email.ToString().Replace("[NumeroEvento]", obtenerEvento.CodigoEvento.ToString());
                email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
                email = email.ToString().Replace("[UrlWeb]", "www.hotmail.com");
                dataEmail.Mensaje = email;
                adjunto = false;
            }
            if (DatosConstantes.EstadoEvento.Aprobado == estado)
            {
                dataEmail.Asunto = string.Concat("Aprobación Presupuesto ", obtenerEvento.CodigoEvento);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlAprobadoPresupuesto.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                email = email.ToString().Replace("[NumeroEvento]", obtenerEvento.CodigoEvento.ToString());
                email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
                email = email.ToString().Replace("[NumeroCelular]", obtenerEvento.TelefonoContacto);
                email = email.ToString().Replace("[EmailContacto]", obtenerEvento.CorreoElectronicoContacto);

                dataEmail.Mensaje = email;
                adjunto = false;
            }
            if (DatosConstantes.EstadoEvento.Aceptado == estado)
            {
                dataEmail.ConCopia.Add(new DataDirecciones() { Email = obtenerEvento.CorreoElectronico, NombreCompleto = obtenerEvento.NombreCliente });
                dataEmail.Asunto = string.Concat("Aceptación Presupuesto ", obtenerEvento.CodigoEvento);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlAceptadoPresupuesto.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                email = email.ToString().Replace("[NumeroEvento]", obtenerEvento.CodigoEvento.ToString());
                email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
                email = email.ToString().Replace("[NumeroCelular]", obtenerEvento.TelefonoContacto);
                email = email.ToString().Replace("[EmailContacto]", obtenerEvento.CorreoElectronicoContacto);

                dataEmail.Mensaje = email;
                adjunto = true;
            }


            if (adjunto)
            {
                var renderedBytes = GenerarDocumentoEvento(codigo, "PDF").Result;
                dataEmail.Adjuntos.Add(new DataAdjuntos() { Archivo = renderedBytes, NombreArchivo = "Presupuesto.pdf" });
            }
            resultado = correoService.Enviar(dataEmail);
            return resultado;
        }

        public ProcessResult<List<DataEventoDetalle>> BuscarEventoDetalle(int codigoEvento, int codigoProveedor = 0)
        {
            ProcessResult<List<DataEventoDetalle>> resultado = new ProcessResult<List<DataEventoDetalle>>();
            try
            {
                var listado = eventoRepository.BuscarDetalle(codigoEvento: codigoEvento, codigoProveedor: codigoProveedor);

                resultado.Result = listado.Select(x => new DataEventoDetalle
                {
                    CodigoArticulo = x.CodigoArticulo,
                    CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                    Cantidad = x.Cantidad,
                    NombreArticulo = x.NombreArticulo,
                    PrecioUnitario = x.PrecioArticulo,
                    MontoTotal = x.MontoTotal
                }).ToList();

            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<byte[]> GenerarDocumentoEvento(int codigo, string formato)
        {
            ProcessResult<byte[]> resultado = new ProcessResult<byte[]>();
            try
            {
                var obtenerEvento = this.ObtenerEvento(codigo).Result;

                List<DataEvento> lstEvento = new List<DataEvento>();
                lstEvento.Add(obtenerEvento);

                LocalReport localReport = new LocalReport();
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/ReportesRDLC"), "rptPresupuestos.rdlc");
                if (System.IO.File.Exists(path))
                {
                    localReport.ReportPath = path;
                }
                localReport.DataSources.Clear();

                ReportDataSource rd = new ReportDataSource("dtsPresupuesto", lstEvento.Select(row => new
                {
                    row.CodigoEvento,
                    row.NombreEvento,
                    row.CodigoTipoEvento,
                    row.FechaEvento,
                    row.LugarEvento,
                    row.NombreEncargado,
                    row.Objetivo,
                    row.Observaciones,
                    row.EsPresupuesto,
                    row.MontoSubTotal,
                    row.MontoIgv,
                    row.MontoTotal,
                    row.CodigoMoneda,
                    row.NombreMoneda,
                    row.CodigoEstado,

                    row.CodigoCliente,
                    row.NombreCliente,
                    row.Telefono,
                    row.NumeroDocumento,
                    row.CorreoElectronico,

                    row.DocumentoContacto,
                    row.NombreContacto,
                    row.CorreoElectronicoContacto,
                    row.TelefonoContacto,

                    row.NombreEstado,
                    row.NombreTipoEvento
                }));
                localReport.DataSources.Add(rd);

                rd = new ReportDataSource("dtsPresupuestoDetalle", lstEvento.FirstOrDefault().ListaEventoDetalle.Select(row => new
                {
                    row.CodigoArticuloProveedor,
                    row.CodigoArticulo,
                    row.CodigoProveedor,
                    row.NombreGrupo,
                    row.NombreArticulo,
                    row.NombreProveedor,
                    row.Cantidad,
                    row.PrecioUnitario,
                    row.MontoTotal
                }));

                localReport.DataSources.Add(rd);

                localReport.Refresh();
                string reportType = formato;
                string mimeType;
                string encoding;
                string fileNameExtension;

                string deviceInfo = "<DeviceInfo>" +
                "  <OutputFormat>" + formato + "</OutputFormat>" +
                "  <PageWidth>8.5in</PageWidth>" +
                "  <PageHeight>11in</PageHeight>" +
                "  <MarginTop>0.5in</MarginTop>" +
                "  <MarginLeft>0.5in</MarginLeft>" +
                "  <MarginRight>0.5in</MarginRight>" +
                "  <MarginBottom>0.5in</MarginBottom>" +
                "</DeviceInfo>";

                Warning[] warnings;
                string[] streams;
                resultado.Result = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);



                //var documento = new ExcelFileManager();
                //var hoja = new WorkSheet();
                //var filas = new List<RowData>();
                //int columnaInicio = 2;
                //uint filaIndice = 2;


                //var cabecera = GenerarDocumentoEventoCabecera(filaIndice, columnaInicio, evento);
                //filaIndice += (uint)cabecera.Count;
                //filas.AddRange(cabecera);

                //filaIndice++;

                //var detalle = GenerarDocumentoEventoDetalle(filaIndice, columnaInicio, evento.ListaEventoDetalle);
                //filaIndice += (uint)detalle.Count;
                //filas.AddRange(detalle);

                //filaIndice++;

                //var pie = GenerarDocumentoEventoPie(filaIndice, columnaInicio, evento);
                //filaIndice += (uint)pie.Count;
                //filas.AddRange(pie);

                //hoja.Rows = filas;

                //resultado.Result = documento.CreateNewDocument(hoja);
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        private List<RowData> GenerarDocumentoEventoCabecera(uint rowIndex, int colmunStart, DataEvento evento)
        {

            var datosCabecera = new Dictionary<string, string>();
            datosCabecera.Add("Evento", evento.NombreEvento);
            datosCabecera.Add("Cliente", evento.NombreCliente);
            datosCabecera.Add("Fecha", evento.FechaEvento);
            datosCabecera.Add("Lugar", evento.LugarEvento);
            datosCabecera.Add("Objetivo", evento.Objetivo);

            var rows = new List<RowData>();

            foreach (var datoCabecera in datosCabecera)
            {
                var row = new RowData(rowIndex);

                var cells = new List<CellData>();
                var cell = new CellData();

                cell = new CellData(colmunStart, rowIndex);
                cell.Value = datoCabecera.Key;
                cell.DataType = "System.String";
                cells.Add(cell);

                cell = new CellData(colmunStart + 1, rowIndex);
                cell.Value = datoCabecera.Value;
                cell.DataType = "System.String";
                cells.Add(cell);

                row.Cells = cells;
                rows.Add(row);

                rowIndex++;
            }

            return rows;
        }

        private List<RowData> GenerarDocumentoEventoDetalle(uint rowIndex, int colmunStart, List<DataEventoDetalle> datosDetalle)
        {
            var rows = new List<RowData>();
            var hoja = new WorkSheet();
            var documento = new ExcelFileManager();
            var indexColumn = colmunStart;
            var diccionario = new Dictionary<int, string>();
            diccionario.Add(indexColumn++, "NombreArticulo");
            diccionario.Add(indexColumn++, "Cantidad");
            diccionario.Add(indexColumn++, "PrecioUnitario");
            diccionario.Add(indexColumn++, "MontoTotal");


            var cabecera = new List<string>();

            cabecera.Add("DETALLE SERVICIO");
            cabecera.Add("CANT.");
            cabecera.Add("C. UNITARIO");
            cabecera.Add("C. TOTAL");

            RowData headerRow = new RowData(rowIndex);
            headerRow.DefaultStyleId = "detalleCabecera";
            headerRow.SetValues(cabecera.ToArray(), 1);
            rows.Add(headerRow);
            rowIndex++;

            datosDetalle = datosDetalle.OrderBy(x => x.NombreGrupo).ToList();

            DataEventoDetalle detalleActual = null;
            DataEventoDetalle detalleAnterior = null;

            for (int i = 0; i < datosDetalle.Count; i++)
            {
                detalleActual = datosDetalle[i];

                if (detalleAnterior == null || detalleActual.NombreGrupo != detalleAnterior.NombreGrupo)
                {
                    var rowGroup = new RowData(rowIndex);
                    rowGroup.DefaultStyleId = "detalleGrupo";
                    rowGroup.Cells = new List<CellData>();

                    var cell = new CellData();
                    cell = new CellData(colmunStart, rowIndex);
                    cell.Value = detalleActual.NombreGrupo;
                    cell.DataType = "System.String";
                    var mergeCellName = cell.ConvertIndexToColumnName(colmunStart + cabecera.Count - 1);
                    cell.CellsRange = cell.CellReference + ":" + mergeCellName + rowIndex;

                    rowGroup.Cells.Add(cell);
                    rows.Add(rowGroup);
                    rowIndex++;
                    //celda = documento.CreateCell(tituloColumna, posicionColumna + contador, posicionFila, posicionCeldaFinalMerge, (int)Enums.ParametrosDireccionMergeExcel.DireccionHorizontal, estilo);
                }

                var row = new RowData(rowIndex);
                row.DefaultStyleId = "detalleDatos";
                row.Cells = hoja.MapperToCells(diccionario, rowIndex, detalleActual);
                rows.Add(row);


                detalleAnterior = detalleActual;
                rowIndex++;
            }

            return rows;
        }

        //public CellData CreateCell(dynamic value, int columnPosition, uint rowPosition, int finalPositionMergeCell, int direction, string style)
        //{
        //    CellData cell;
        //    string mergeCellName;
        //    string cellsRange;
        //    int finalPosition;

        //    cell = new CellData(columnPosition, rowPosition) { Value = value != null ? value.ToString() : "" };
        //    cell.StyleId = style;

        //    cell.DataType = Enums.ParametroGlobal.TipoDatoDefault;
        //    if (value != null) { cell.DataType = value.GetType().FullName; }

        //    if ((int)Enums.ParametrosDireccionMergeExcel.DireccionHorizontal == direction)
        //    {
        //        finalPosition = (int)rowPosition;
        //        mergeCellName = cell.ConvertIndexToColumnName(finalPositionMergeCell);
        //    }
        //    else
        //    {
        //        mergeCellName = cell.CellName;
        //        finalPosition = finalPositionMergeCell;
        //    }

        //    cellsRange = cell.CellReference + ":" + mergeCellName + finalPosition;
        //    cell.CellsRange = cellsRange;

        //    return cell;
        //}

        //public CellData CreateCell(dynamic value, int columnPosition, uint rowPosition, string cellsRange, string style)
        //{
        //    CellData cell;
        //    cell = new CellData(columnPosition, rowPosition) { Value = value != null ? value.ToString() : "" };
        //    cell.StyleId = style;
        //    cell.CellsRange = cellsRange;
        //    cell.DataType = Enums.ParametroGlobal.TipoDatoDefault;
        //    if (value != null) { cell.DataType = value.GetType().FullName; }

        //    return cell;
        //}

        private List<RowData> GenerarDocumentoEventoPie(uint rowIndex, int colmunStart, DataEvento evento)
        {

            var diccionarioPie = new Dictionary<string, decimal>();
            diccionarioPie.Add("Total Bruto", evento.MontoSubTotal);
            diccionarioPie.Add("IGV (18%)", evento.MontoIgv);
            diccionarioPie.Add("Total Presupuestado", evento.MontoTotal);

            var rows = new List<RowData>();

            foreach (var datoCabecera in diccionarioPie)
            {
                var row = new RowData(rowIndex);

                var cells = new List<CellData>();
                var cell = new CellData();

                cell = new CellData(colmunStart + 2, rowIndex);
                cell.Value = datoCabecera.Key;
                cell.DataType = "System.String";
                cells.Add(cell);

                cell = new CellData(colmunStart + 3, rowIndex);
                cell.Value = datoCabecera.Value.ToString();
                cell.DataType = "System.Decimal";
                cells.Add(cell);

                row.Cells = cells;
                rows.Add(row);

                rowIndex++;
            }

            return rows;
        }
        #endregion

        #region Proyecto
        public ProcessResult<List<DataProyecto>> BuscarProyecto(FiltroProyecto filtro)
        {
            ProcessResult<List<DataProyecto>> resultado = new ProcessResult<List<DataProyecto>>();
            try
            {
                var fechaInicio = Formato.StringFormatDatetime(filtro.FechaInicio);
                var fechaFin = Formato.StringFormatDatetime(filtro.FechaFin);

                var listado = proyectoRepository.Buscar(codigoCliente: filtro.CodigoCliente, codigoEstado: filtro.CodigoEstado, nombreCliente: filtro.NombreCliente, nombreProyecto: filtro.NombreProyecto, fechaInicio: fechaInicio, fechaFin: fechaFin);

                resultado.Result = listado.Select(x => new DataProyecto
                {
                    CodigoProyecto = x.CodigoProyecto,
                    NombreProyecto = x.NombreProyecto,
                    CodigoEvento = x.CodigoEvento,
                    CodigoTipoProyecto = x.CodigoTipoProyecto,
                    FechaProyecto = Formato.DatetimeFormatString(x.FechaProyecto),
                    LugarProyecto = x.LugarProyecto,
                    NombreEncargado = x.NombreEncargado,
                    Objetivo = x.Objetivo,
                    Observaciones = x.Observaciones,
                    EsPresupuesto = x.EsPresupuesto,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoTotal = x.MontoTotal,
                    CodigoMoneda = x.CodigoMoneda,
                    NombreMoneda = x.NombreMoneda,
                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    CodigoCliente = x.CodigoCliente,
                    NombreCliente = x.NombreCliente,
                    Telefono = x.Telefono,
                    NumeroDocumento = x.NumeroDocumento,
                    CorreoElectronico = x.CorreoElectronico,

                    DocumentoContacto = x.DocumentoContacto,
                    NombreContacto = x.NombreContacto,
                    CorreoElectronicoContacto = x.CorreoElectronicoContacto,
                    TelefonoContacto = x.TelefonoContacto,

                    NombreEstado = x.NombreEstado,
                    NombreTipoProyecto = x.NombreTipoProyecto
                }).ToList();
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataProyecto> ObtenerProyecto(int codigo)
        {
            ProcessResult<DataProyecto> resultado = new ProcessResult<DataProyecto>();
            try
            {
                var listado = proyectoRepository.Buscar(codigoProyecto: codigo);
                var proyecto = listado.Select(x => new DataProyecto
                {
                    CodigoProyecto = x.CodigoProyecto,
                    NombreProyecto = x.NombreProyecto,
                    CodigoTipoProyecto = x.CodigoTipoProyecto,
                    FechaProyecto = Formato.DatetimeFormatString(x.FechaProyecto),
                    LugarProyecto = x.LugarProyecto,
                    NombreEncargado = x.NombreEncargado,
                    Objetivo = x.Objetivo,
                    Observaciones = x.Observaciones,
                    EsPresupuesto = x.EsPresupuesto,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoTotal = x.MontoTotal,
                    CodigoMoneda = x.CodigoMoneda,
                    NombreMoneda = x.NombreMoneda,
                    CodigoEstado = x.CodigoEstado,

                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaModificacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    CodigoCliente = x.CodigoCliente,
                    NombreCliente = x.NombreCliente,
                    Telefono = x.Telefono,
                    NumeroDocumento = x.NumeroDocumento,
                    CorreoElectronico = x.CorreoElectronico,

                    DocumentoContacto = x.DocumentoContacto,
                    NombreContacto = x.NombreContacto,
                    CorreoElectronicoContacto = x.CorreoElectronicoContacto,
                    TelefonoContacto = x.TelefonoContacto,

                    NombreEstado = x.NombreEstado,
                    NombreTipoProyecto = x.NombreTipoProyecto,

                    CodigoUsuario = x.CodigoUsuario,
                    NombreUsuarioCompleto = x.NombreUsuarioCompleto,
                    EmailUsuario = x.EmailUsuario
                }).FirstOrDefault();

                if (proyecto != null)
                {
                    proyecto.ListaProyectoDetalle = proyectoRepository.BuscarDetalle(proyecto.CodigoProyecto).Select(x => new DataProyectoDetalle
                    {
                        CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                        CodigoArticulo = x.CodigoArticulo,
                        CodigoProveedor = x.CodigoProveedor,
                        NombreGrupo = x.NombreGrupo,
                        NombreArticulo = x.NombreArticulo,
                        NombreProveedor = x.NombreProveedor,
                        Cantidad = x.Cantidad,
                        PrecioUnitario = x.PrecioArticulo,
                        MontoTotal = x.MontoTotal
                    }).ToList();
                }

                resultado.Result = proyecto;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataProyecto> RegistrarProyecto(DataProyecto proyecto)
        {
            ProcessResult<DataProyecto> resultado = new ProcessResult<DataProyecto>();
            try
            {
                var proyectoRegistro = new ProyectoEntity();
                proyectoRegistro.CodigoProyecto = proyecto.CodigoProyecto;
                proyectoRegistro.Observaciones = proyecto.Observaciones;


                proyectoRegistro.UsuarioCreacion = proyecto.UsuarioCreacion;
                proyectoRegistro.UsuarioModificacion = proyecto.UsuarioModificacion;

                proyectoRegistro.ListaProyectoDetalle = proyecto.ListaProyectoDetalle.Select(x => new ProyectoDetalleEntity
                {
                    CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                    NombreGrupo = x.NombreGrupo,
                    PrecioArticulo = x.PrecioUnitario,
                    Cantidad = x.Cantidad,
                    MontoTotal = x.PrecioUnitario * x.Cantidad
                }).ToList();

                proyectoRegistro.MontoSubTotal = proyectoRegistro.ListaProyectoDetalle.Sum(x => x.MontoTotal);
                proyectoRegistro.MontoIgv = proyectoRegistro.MontoSubTotal * DatosConstantes.Monto.Igv;
                proyectoRegistro.MontoTotal = proyectoRegistro.MontoSubTotal + proyectoRegistro.MontoIgv;

                //if (proyecto.CodigoProyecto == 0)
                //{
                //    proyectoRegistro.CodigoEstado = DatosConstantes.EstadoEvento.Registrado;
                //    proyectoRegistro.EsPresupuesto = true;
                //    proyecto.CodigoProyecto = proyectoRepository.Insertar(proyectoRegistro);
                //}
                //else
                //{
                //proyectoRegistro.ListaProyectoDetalle


                proyectoRepository.Modificar(proyectoRegistro);
                //}

                resultado.Result = ObtenerProyecto(proyecto.CodigoProyecto).Result;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<DataProyectoDetalle>> BuscarProyectoDetalle(int codigoProyecto, int codigoProveedor = 0)
        {
            ProcessResult<List<DataProyectoDetalle>> resultado = new ProcessResult<List<DataProyectoDetalle>>();
            try
            {
                var listado = proyectoRepository.BuscarDetalle(codigoProyecto: codigoProyecto, codigoProveedor: codigoProveedor);

                resultado.Result = listado.Select(x => new DataProyectoDetalle
                {
                    CodigoArticulo = x.CodigoArticulo,
                    CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                    Cantidad = x.Cantidad,
                    NombreArticulo = x.NombreArticulo,
                    NombreProveedor = x.NombreProveedor,
                    PrecioUnitario = x.PrecioArticulo,
                    MontoTotal = x.MontoTotal
                }).ToList();

            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<DataProyectoDetalle>> BuscarProyectoDetallexOC(int codigoProyecto, int codigoProveedor = 0)
        {
            ProcessResult<List<DataProyectoDetalle>> resultado = new ProcessResult<List<DataProyectoDetalle>>();
            try
            {
                var listado = proyectoRepository.BuscarDetalleXoc(codigoProyecto: codigoProyecto, codigoProveedor: codigoProveedor);

                resultado.Result = listado.Select(x => new DataProyectoDetalle
                {
                    CodigoArticulo = x.CodigoArticulo,
                    CodigoArticuloProveedor = x.CodigoArticuloProveedor,
                    Cantidad = x.Cantidad,
                    NombreArticulo = x.NombreArticulo,
                    PrecioUnitario = x.PrecioArticulo,
                    MontoTotal = x.MontoTotal
                }).ToList();

            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<int>> ModificarEstadoProyecto(List<int> codigos, string estado, string usuario)
        {
            ProcessResult<List<int>> resultado = new ProcessResult<List<int>>();
            try
            {
                var listado = proyectoRepository.ModificarEstado(codigos, estado, usuario);
                if (DatosConstantes.EstadoProyecto.PreAprobado == estado || DatosConstantes.EstadoProyecto.Aprobado == estado)
                {
                    foreach (var item in codigos)
                    {
                        EnviarProyecto(item, estado);
                    }
                }
                resultado.Result = codigos;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }
        public ProcessResult<string> EnviarProyecto(int codigo, string estado)
        {
            ProcessResult<string> resultado = new ProcessResult<string>();
            bool adjunto = false;
            DataEmail dataEmail = new DataEmail();
            var obtenerEvento = ObtenerProyecto(codigo).Result;
            dataEmail.Para.Add(new DataDirecciones() { Email = obtenerEvento.EmailUsuario, NombreCompleto = obtenerEvento.NombreUsuarioCompleto });

            var emailAdministradores = generalService.BuscarOpcion(DatosConstantes.Parametro.EmailAdministradores).Result;
            foreach (var item in emailAdministradores)
            {
                dataEmail.ConCopia.Add(new DataDirecciones() { Email = item.Nombre, NombreCompleto = item.Nombre });
            }

            if (DatosConstantes.EstadoProyecto.PreAprobado == estado)
            {
                dataEmail.Asunto = string.Concat("Pre Aprobación Proyecto ", obtenerEvento.CodigoProyecto);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlPreAprobadoProyecto.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                email = email.ToString().Replace("[NumeroProyecto]", obtenerEvento.CodigoProyecto.ToString());
                email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
                email = email.ToString().Replace("[UrlWeb]", "www.hotmail.com");
                dataEmail.Mensaje = email;
                adjunto = false;
            }
            if (DatosConstantes.EstadoProyecto.Aprobado == estado)
            {
                dataEmail.Asunto = string.Concat("Aprobación Proyecto ", obtenerEvento.CodigoProyecto);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlAprobadoProyecto.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                email = email.ToString().Replace("[NumeroProyecto]", obtenerEvento.CodigoProyecto.ToString());
                email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
                email = email.ToString().Replace("[NumeroCelular]", obtenerEvento.TelefonoContacto);
                email = email.ToString().Replace("[EmailContacto]", obtenerEvento.CorreoElectronicoContacto);

                dataEmail.Mensaje = email;
                adjunto = false;
            }
            //if (DatosConstantes.EstadoProyecto.Aceptado == estado)
            //{
            //    //dataEmail.ConCopia.Add(new DataDirecciones() { Email = obtenerEvento.CorreoElectronico, NombreCompleto = obtenerEvento.NombreCliente });
            //    dataEmail.Asunto = string.Concat("Aceptación Proyecto ", obtenerEvento.CodigoProyecto);
            //    string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlAceptadoProyecto.html");
            //    StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
            //    var email = emailHtml.ToString();
            //    email = email.ToString().Replace("[NumeroProyecto]", obtenerEvento.CodigoProyecto.ToString());
            //    email = email.ToString().Replace("[NombreCliente]", obtenerEvento.NombreCliente);
            //    email = email.ToString().Replace("[NumeroCelular]", obtenerEvento.TelefonoContacto);
            //    email = email.ToString().Replace("[EmailContacto]", obtenerEvento.CorreoElectronicoContacto);

            //    dataEmail.Mensaje = email;
            //    //adjunto = true;
            //}


            if (adjunto)
            {
                var renderedBytes = GenerarDocumentoEvento(codigo, "PDF").Result;
                dataEmail.Adjuntos.Add(new DataAdjuntos() { Archivo = renderedBytes, NombreArchivo = "Presupuesto.pdf" });
            }
            resultado = correoService.Enviar(dataEmail);
            return resultado;
        }
        public ProcessResult<byte[]> GenerarDocumentoProyecto(int codigo, string formato)
        {
            ProcessResult<byte[]> resultado = new ProcessResult<byte[]>();
            try
            {
                var obtenerProyecto = this.ObtenerProyecto(codigo).Result;

                List<DataProyecto> lstProyecto = new List<DataProyecto>();
                lstProyecto.Add(obtenerProyecto);

                LocalReport localReport = new LocalReport();
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/ReportesRDLC"), "rptProyecto.rdlc");
                if (System.IO.File.Exists(path))
                {
                    localReport.ReportPath = path;
                }
                localReport.DataSources.Clear();

                ReportDataSource rd = new ReportDataSource("dtsProyecto", lstProyecto.Select(row => new
                {
                    row.CodigoProyecto,
                    row.NombreProyecto,
                    row.CodigoTipoProyecto,
                    row.FechaProyecto,
                    row.LugarProyecto,
                    row.NombreEncargado,
                    row.Objetivo,
                    row.Observaciones,
                    row.EsPresupuesto,
                    row.MontoSubTotal,
                    row.MontoIgv,
                    row.MontoTotal,
                    row.CodigoMoneda,
                    row.NombreMoneda,
                    row.CodigoEstado,

                    row.CodigoCliente,
                    row.NombreCliente,
                    row.Telefono,
                    row.NumeroDocumento,
                    row.CorreoElectronico,

                    row.DocumentoContacto,
                    row.NombreContacto,
                    row.CorreoElectronicoContacto,
                    row.TelefonoContacto,

                    row.NombreEstado,
                    row.NombreTipoProyecto,

                    row.CodigoUsuario,
                    row.NombreUsuarioCompleto,
                    row.EmailUsuario
                }));
                localReport.DataSources.Add(rd);

                rd = new ReportDataSource("dtsProyectoDetalle", lstProyecto.FirstOrDefault().ListaProyectoDetalle.Select(row => new
                {
                    row.CodigoArticuloProveedor,
                    row.CodigoArticulo,
                    row.CodigoProveedor,
                    row.NombreGrupo,
                    row.NombreArticulo,
                    row.NombreProveedor,
                    row.Cantidad,
                    row.PrecioUnitario,
                    row.MontoTotal
                }));

                localReport.DataSources.Add(rd);

                localReport.Refresh();
                string reportType = formato;
                string mimeType;
                string encoding;
                string fileNameExtension;

                string deviceInfo = "<DeviceInfo>" +
                "  <OutputFormat>" + formato + "</OutputFormat>" +
                "  <PageWidth>8.5in</PageWidth>" +
                "  <PageHeight>11in</PageHeight>" +
                "  <MarginTop>0.5in</MarginTop>" +
                "  <MarginLeft>0.5in</MarginLeft>" +
                "  <MarginRight>0.5in</MarginRight>" +
                "  <MarginBottom>0.5in</MarginBottom>" +
                "</DeviceInfo>";

                Warning[] warnings;
                string[] streams;
                resultado.Result = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<string> ValidarItemsProyecto(int codigoProyecto, int codigoArticuloProveedor = 0)
        {
            ProcessResult<string> resultado = new ProcessResult<string>();
            try
            {
                var listado = proyectoRepository.ValidarItemsProyecto(codigoProyecto, codigoArticuloProveedor);
                resultado.Result = listado.Sum(p => p.Cantidad).ToString();
                resultado.IsSuccess = true;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }
        #endregion

        #region Orden Compra
        public ProcessResult<List<DataOrdenCompra>> BuscarOrdenCompra(FiltroOrdenCompra filtro)
        {
            ProcessResult<List<DataOrdenCompra>> resultado = new ProcessResult<List<DataOrdenCompra>>();
            try
            {
                var fechaInicio = Formato.StringFormatDatetime(filtro.FechaInicio);
                var fechaFin = Formato.StringFormatDatetime(filtro.FechaFin);

                var listado = ordenCompraRepository.Buscar(codigoProveedor: filtro.CodigoProveedor, codigoProyecto: filtro.CodigoProyecto,
                    codigoEstado: filtro.CodigoEstado, nombreProveedor: filtro.NombreProveedor, nombreProyecto: filtro.NombreProyecto,
                    fechaInicio: fechaInicio, fechaFin: fechaFin);

                resultado.Result = listado.Select(x => new DataOrdenCompra
                {
                    CodigoOrdenCompra = x.CodigoOrdenCompra,
                    CodigoProyecto = x.CodigoProyecto,
                    CodigoProveedor = x.CodigoProveedor,
                    CodigoMoneda = x.CodigoMoneda,
                    FechaEntrega = Formato.DatetimeFormatString(x.FechaEntrega),
                    LugarEntrega = x.LugarEntrega,
                    Observaciones = x.Observaciones,
                    MontoAdelanto = x.MontoAdelanto,
                    NumeroCuota = x.NumeroCuota,
                    FrecuenciaCuota = x.FrecuenciaCuota,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoDetraccion = x.MontoDetraccion,
                    MontoTotal = x.MontoTotal,

                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    NombreProyecto = x.NombreProyecto,
                    CodigoMonedaProyecto = x.CodigoMonedaProyecto,

                    NombreProveedor = x.NombreProveedor,
                    NumeroDocumento = x.NumeroDocumento,
                    DireccionProveedor = x.DireccionProveedor,
                    DistritoProveedor = x.DistritoProveedor,
                    NombreContactoProveedor = x.NombreContactoProveedor,
                    CorreoElectronicoProveedor = x.CorreoElectronicoProveedor,
                    TieneDetraccion = x.TieneDetraccion,

                    NombreEstado = x.NombreEstado,
                    NombreMoneda = x.NombreMoneda,

                    /*Se agrego para la busqueda de orden de compra en los comprobantes de pago*/
                    TipoDePagoComprobante = x.TipoDePagoComprobante == "A" ? "Adelanto" : "Cuota",
                    AdelantoPorPagarComprobante = x.AdelantoPorPagarComprobante,
                    NroUltimaCuotaPagadaComprobante = x.NroUltimaCuotaPagadaComprobante,
                    MontoPorPagarComprobante = x.MontoPorPagarComprobante,
                    FechaCuotaAtualPorPagarComprobante = Formato.DatetimeFormatString(x.FechaCuotaAtualPorPagarComprobante),
                    NroCuotaActualComprobante = x.NroCuotaActualComprobante
                    /*Fin*/
                }).ToList();
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        //public ProcessResult<List<DataOrdenCompra>> ReporteOrdenCompra(FiltroOrdenCompra filtro)
        //{
        //    ProcessResult<List<DataOrdenCompra>> resultado = new ProcessResult<List<DataOrdenCompra>>();
        //    try
        //    {
        //        var listado = ordenCompraRepository.Reporte(codigoOrdenCompra: filtro.CodigoOrdenCompra);
        //        resultado.Result = listado.Select(x => new DataOrdenCompra
        //        {
        //            CodigoOrdenCompra = x.CodigoOrdenCompra,
        //            CodigoProyecto = x.CodigoProyecto,
        //            CodigoProveedor = x.CodigoProveedor,
        //            CodigoMoneda = x.CodigoMoneda,
        //            FechaEntrega = Formato.DatetimeFormatString(x.FechaEntrega),
        //            LugarEntrega = x.LugarEntrega,
        //            Observaciones = x.Observaciones,
        //            MontoAdelanto = x.MontoAdelanto,
        //            NumeroCuota = x.NumeroCuota,
        //            FrecuenciaCuota = x.FrecuenciaCuota,
        //            MontoSubTotal = x.MontoSubTotal,
        //            MontoIgv = x.MontoIgv,
        //            MontoDetraccion = x.MontoDetraccion,
        //            MontoTotal = x.MontoTotal,
        //            CodigoEstado = x.CodigoEstado,
        //            UsuarioCreacion = x.UsuarioCreacion,
        //            FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
        //            UsuarioModificacion = x.UsuarioModificacion,
        //            FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),
        //            NombreProyecto = x.NombreProyecto,
        //            CodigoMonedaProyecto = x.CodigoMonedaProyecto,
        //            NombreProveedor = x.NombreProveedor,
        //            NumeroDocumento = x.NumeroDocumento,
        //            DireccionProveedor = x.DireccionProveedor,
        //            DistritoProveedor = x.DistritoProveedor,
        //            NombreContactoProveedor = x.NombreContactoProveedor,
        //            CorreoElectronicoProveedor = x.CorreoElectronicoProveedor,
        //            TieneDetraccion = x.TieneDetraccion,
        //            NombreEstado = x.NombreEstado,
        //            NombreMoneda = x.NombreMoneda
        //        }).ToList();
        //    }
        //    catch (Exception e)
        //    {
        //        resultado.IsSuccess = false;
        //        resultado.Exception = new ApplicationLayerException<VentasService>(e);
        //    }

        //    return resultado;
        //}

        public ProcessResult<DataOrdenCompra> ObtenerOrdenCompra(int codigo)
        {
            ProcessResult<DataOrdenCompra> resultado = new ProcessResult<DataOrdenCompra>();
            try
            {
                var listado = ordenCompraRepository.Buscar(codigoOrdenCompra: codigo);
                var ordenCompra = listado.Select(x => new DataOrdenCompra
                {
                    CodigoOrdenCompra = x.CodigoOrdenCompra,
                    CodigoProyecto = x.CodigoProyecto,
                    CodigoProveedor = x.CodigoProveedor,
                    CodigoMoneda = x.CodigoMoneda,
                    FechaEntrega = Formato.DatetimeFormatString(x.FechaEntrega),
                    LugarEntrega = x.LugarEntrega,
                    Observaciones = x.Observaciones,
                    MontoAdelanto = x.MontoAdelanto,
                    NumeroCuota = x.NumeroCuota,
                    FrecuenciaCuota = x.FrecuenciaCuota,
                    MontoSubTotal = x.MontoSubTotal,
                    MontoIgv = x.MontoIgv,
                    MontoDetraccion = x.MontoDetraccion,
                    MontoTotal = x.MontoTotal,

                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),

                    NombreProyecto = x.NombreProyecto,
                    CodigoMonedaProyecto = x.CodigoMonedaProyecto,

                    NombreProveedor = x.NombreProveedor,
                    NumeroDocumento = x.NumeroDocumento,
                    DireccionProveedor = x.DireccionProveedor,
                    DistritoProveedor = x.DistritoProveedor,
                    NombreContactoProveedor = x.NombreContactoProveedor,
                    CorreoElectronicoProveedor = x.CorreoElectronicoProveedor,
                    TieneDetraccion = x.TieneDetraccion,

                    NombreEstado = x.NombreEstado,
                    NombreMoneda = x.NombreMoneda,

                    CodigoUsuario = x.CodigoUsuario,
                    NombreUsuarioCompleto = x.NombreUsuarioCompleto,
                    EmailUsuario = x.EmailUsuario
                }).FirstOrDefault();

                if (ordenCompra != null)
                {
                    ordenCompra.ListaOrdenCompraDetalle = ordenCompraRepository.BuscarDetalle(ordenCompra.CodigoOrdenCompra).Select(x => new DataOrdenCompraDetalle
                    {
                        CodigoOrdenCompra = x.CodigoOrdenCompra,
                        CodigoArticulo = x.CodigoArticulo,
                        NombreArticulo = x.NombreArticulo,
                        Cantidad = x.Cantidad,
                        PrecioArticulo = x.PrecioArticulo,
                        MontoTotal = x.MontoTotal
                    }).ToList();
                }

                resultado.Result = ordenCompra;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataOrdenCompra> RegistrarOrdenCompra(DataOrdenCompra ordenCompra)
        {
            ProcessResult<DataOrdenCompra> resultado = new ProcessResult<DataOrdenCompra>();
            try
            {
                var ordenRegistro = new OrdenCompraEntity();
                ordenRegistro.CodigoOrdenCompra = ordenCompra.CodigoOrdenCompra;
                ordenRegistro.CodigoProyecto = ordenCompra.CodigoProyecto;
                ordenRegistro.CodigoProveedor = ordenCompra.CodigoProveedor;
                ordenRegistro.CodigoMoneda = ordenCompra.CodigoMoneda;
                ordenRegistro.FechaEntrega = Formato.StringFormatDatetime(ordenCompra.FechaEntrega).Value;
                ordenRegistro.LugarEntrega = ordenCompra.LugarEntrega;
                ordenRegistro.Observaciones = ordenCompra.Observaciones;
                ordenRegistro.NumeroCuota = ordenCompra.NumeroCuota;
                ordenRegistro.MontoAdelanto = ordenCompra.MontoAdelanto;
                ordenRegistro.FrecuenciaCuota = ordenCompra.FrecuenciaCuota;

                ordenRegistro.UsuarioCreacion = ordenCompra.UsuarioCreacion;
                ordenRegistro.UsuarioModificacion = ordenCompra.UsuarioModificacion;

                ordenRegistro.ListaOrdenCompraDetalle = ordenCompra.ListaOrdenCompraDetalle.Select(x => new OrdenCompraDetalleEntity
                {
                    CodigoArticulo = x.CodigoArticulo,
                    PrecioArticulo = x.PrecioArticulo,
                    Cantidad = x.Cantidad,
                    MontoTotal = x.PrecioArticulo * x.Cantidad
                }).ToList();

                ordenRegistro.MontoSubTotal = ordenRegistro.ListaOrdenCompraDetalle.Sum(x => x.MontoTotal);
                ordenRegistro.MontoIgv = ordenRegistro.MontoSubTotal * DatosConstantes.Monto.Igv;
                ordenRegistro.MontoTotal = ordenRegistro.MontoSubTotal + ordenRegistro.MontoIgv;
                //detraccion
                var detraccion = ordenRegistro.MontoTotal * DatosConstantes.Monto.Detraccion;
                ordenRegistro.MontoDetraccion = detraccion;

                if (ordenRegistro.CodigoOrdenCompra == 0)
                {
                    ordenRegistro.CodigoEstado = DatosConstantes.EstadoOrdenCompra.Generado;
                    ordenCompra.CodigoOrdenCompra = ordenCompraRepository.Insertar(ordenRegistro);
                }
                else
                {
                    ordenCompraRepository.Modificar(ordenRegistro);
                }

                resultado.Result = ObtenerOrdenCompra(ordenCompra.CodigoOrdenCompra).Result;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<int>> ModificarEstadoOrdenCompra(List<int> codigos, string estado, string usuario)
        {
            ProcessResult<List<int>> resultado = new ProcessResult<List<int>>();
            try
            {
                var listado = ordenCompraRepository.ModificarEstado(codigos, estado, usuario);
                resultado.Result = codigos;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataOrdenCompra> CopiarOrdenCompra(int codigo, string usuario)
        {
            ProcessResult<DataOrdenCompra> resultado = new ProcessResult<DataOrdenCompra>();
            try
            {

                resultado = ObtenerOrdenCompra(codigo);
                resultado.Result.CodigoOrdenCompra = 0;
                resultado.Result.UsuarioCreacion = usuario;

                resultado = RegistrarOrdenCompra(resultado.Result);

            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<string> EnviarOrdenCompra(int codigo, string estado)
        {
            ProcessResult<string> resultado = new ProcessResult<string>();
            bool adjunto = false;
            DataEmail dataEmail = new DataEmail();
            var obtenerOrdenCompra = ObtenerOrdenCompra(codigo).Result;
            dataEmail.Para.Add(new DataDirecciones() { Email = obtenerOrdenCompra.EmailUsuario, NombreCompleto = obtenerOrdenCompra.NombreUsuarioCompleto });

            var emailAdministradores = generalService.BuscarOpcion(DatosConstantes.Parametro.EmailAdministradores).Result;
            foreach (var item in emailAdministradores)
            {
                dataEmail.ConCopia.Add(new DataDirecciones() { Email = item.Nombre, NombreCompleto = item.Nombre });
            }

            if (DatosConstantes.EstadoOrdenCompra.Generado == estado)
            {
                dataEmail.Asunto = string.Concat("Pre Aprobación Presupuesto ", obtenerOrdenCompra.NumeroDocumento);
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlRegistradoOrdenCompra.html");
                StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
                var email = emailHtml.ToString();
                //email = email.ToString().Replace("[NumeroDocumento]", obtenerOrdenCompra.NumeroDocumento);
                //email = email.ToString().Replace("[NombreCliente]", obtenerOrdenCompra.NombreCliente);
                //email = email.ToString().Replace("[UrlWeb]", "www.hotmail.com");
                //dataEmail.Mensaje = email;
                adjunto = false;
            }
            //if (DatosConstantes.EstadoOrdenCompra.Aprobado == estado)
            //{
            //    dataEmail.Asunto = string.Concat("Aprobación Presupuesto ", obtenerOrdenCompra.NumeroDocumento);
            //    string path = Path.Combine(HttpContext.Current.Server.MapPath("~/PlantillaEmail"), "htmlRegistradoOrdenCompra.html");
            //    StringBuilder emailHtml = new StringBuilder(File.ReadAllText(path));
            //    var email = emailHtml.ToString();
            //    //email = email.ToString().Replace("[NumeroDocumento]", obtenerOrdenCompra.NumeroDocumento);
            //    //email = email.ToString().Replace("[NombreCliente]", obtenerOrdenCompra.NombreCliente);
            //    //email = email.ToString().Replace("[NumeroCelular]", obtenerOrdenCompra.TelefonoContacto);
            //    //email = email.ToString().Replace("[EmailCliente]", obtenerOrdenCompra.CorreoElectronicoContacto);

            //    dataEmail.Mensaje = email;
            //    adjunto = true;
            //}

            if (adjunto)
            {
                var renderedBytes = GenerarDocumentoOrdenCompra(codigo, "PDF").Result;
                dataEmail.Adjuntos.Add(new DataAdjuntos() { Archivo = renderedBytes, NombreArchivo = "OrdenCompra.pdf" });
            }
            resultado = correoService.Enviar(dataEmail);
            return resultado;
        }

        public ProcessResult<byte[]> GenerarDocumentoOrdenCompra(int codigo, string formato)
        {
            ProcessResult<byte[]> resultado = new ProcessResult<byte[]>();
            try
            {
                List<DataOrdenCompra> lstOrdenCompra = new List<DataOrdenCompra>();
                lstOrdenCompra.Add(ObtenerOrdenCompra(codigo).Result);

                LocalReport localReport = new LocalReport();
                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/ReportesRDLC"), "rptOrdenCompra.rdlc");
                if (System.IO.File.Exists(path))
                {
                    localReport.ReportPath = path;
                }
                localReport.DataSources.Clear();

                ReportDataSource rd = new ReportDataSource("dtsOrdenCompra", lstOrdenCompra.Select(row => new
                {
                    row.CodigoOrdenCompra,
                    row.CodigoProyecto,
                    row.CodigoProveedor,
                    row.CodigoMoneda,
                    row.FechaEntrega,
                    row.LugarEntrega,
                    row.Observaciones,
                    row.MontoAdelanto,
                    row.NumeroCuota,
                    row.FrecuenciaCuota,
                    row.MontoSubTotal,
                    row.MontoIgv,
                    row.MontoDetraccion,
                    row.MontoTotal,

                    row.CodigoEstado,

                    row.NombreProyecto,
                    row.CodigoMonedaProyecto,

                    row.NombreProveedor,
                    row.NumeroDocumento,
                    row.DireccionProveedor,
                    row.DistritoProveedor,
                    row.NombreContactoProveedor,
                    row.CorreoElectronicoProveedor,
                    row.TieneDetraccion,

                    row.NombreEstado,
                    row.NombreMoneda
                }));
                localReport.DataSources.Add(rd);

                rd = new ReportDataSource("dtsOrdenCompraDetalle", lstOrdenCompra.FirstOrDefault().ListaOrdenCompraDetalle.Select(row => new
                {
                    row.CodigoOrdenCompra,
                    row.CodigoArticulo,
                    row.NombreArticulo,
                    row.Cantidad,
                    row.PrecioArticulo,
                    row.MontoTotal
                }));

                localReport.DataSources.Add(rd);

                localReport.Refresh();
                string reportType = formato;
                string mimeType;
                string encoding;
                string fileNameExtension;

                string deviceInfo = "<DeviceInfo>" +
                "  <OutputFormat>" + formato + "</OutputFormat>" +
                "  <PageWidth>8.5in</PageWidth>" +
                "  <PageHeight>11in</PageHeight>" +
                "  <MarginTop>0.5in</MarginTop>" +
                "  <MarginLeft>0.5in</MarginLeft>" +
                "  <MarginRight>0.5in</MarginRight>" +
                "  <MarginBottom>0.5in</MarginBottom>" +
                "</DeviceInfo>";

                Warning[] warnings;
                string[] streams;
                resultado.Result = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);
                //var ordenCompra = this.ObtenerOrdenCompra(codigo).Result;

                //var documento = new ExcelFileManager();
                //var hoja = new WorkSheet();
                //var filas = new List<RowData>();
                //int columnaInicio = 2;
                //uint filaIndice = 2;

                //var cabecera = GenerarDocumentoOrdenCompraCabecera(filaIndice, columnaInicio, ordenCompra);
                //filaIndice += (uint)cabecera.Count;
                //filas.AddRange(cabecera);

                //filaIndice++;

                //var detalle = GenerarDocumentoOrdenCompraDetalle(filaIndice, columnaInicio, ordenCompra.ListaOrdenCompraDetalle);
                //filaIndice += (uint)detalle.Count;
                //filas.AddRange(detalle);

                //filaIndice++;

                //var pie = GenerarDocumentoOrdenCompraPie(filaIndice, columnaInicio, ordenCompra);
                //filaIndice += (uint)pie.Count;
                //filas.AddRange(pie);

                //hoja.Rows = filas;

                //resultado.Result = documento.CreateNewDocument(hoja);
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        private List<RowData> GenerarDocumentoOrdenCompraCabecera(uint rowIndex, int colmunStart, DataOrdenCompra ordenCompra)
        {

            var datosCabecera = new Dictionary<string, string>();
            datosCabecera.Add("Proveedor", ordenCompra.NombreProveedor);
            datosCabecera.Add("RUC", ordenCompra.NumeroDocumento);
            datosCabecera.Add("Fecha", ordenCompra.FechaEntrega);
            datosCabecera.Add("Lugar", ordenCompra.LugarEntrega);

            var rows = new List<RowData>();

            foreach (var datoCabecera in datosCabecera)
            {
                var row = new RowData(rowIndex);

                var cells = new List<CellData>();
                var cell = new CellData();

                cell = new CellData(colmunStart, rowIndex);
                cell.Value = datoCabecera.Key;
                cell.DataType = "System.String";
                cells.Add(cell);

                cell = new CellData(colmunStart + 1, rowIndex);
                cell.Value = datoCabecera.Value;
                cell.DataType = "System.String";
                cells.Add(cell);

                row.Cells = cells;
                rows.Add(row);

                rowIndex++;
            }

            return rows;
        }

        private List<RowData> GenerarDocumentoOrdenCompraDetalle(uint rowIndex, int colmunStart, List<DataOrdenCompraDetalle> datosDetalle)
        {
            var rows = new List<RowData>();
            var hoja = new WorkSheet();
            var indexColumn = colmunStart;
            var diccionario = new Dictionary<int, string>();
            diccionario.Add(indexColumn++, "NombreArticulo");
            diccionario.Add(indexColumn++, "Cantidad");
            diccionario.Add(indexColumn++, "PrecioArticulo");
            diccionario.Add(indexColumn++, "MontoTotal");


            var cabecera = new List<string>();
            cabecera.Add("ITEM");
            cabecera.Add("CANT.");
            cabecera.Add("C. UNITARIO");
            cabecera.Add("C. TOTAL");

            RowData headerRow = new RowData(rowIndex);
            headerRow.DefaultStyleId = "detalleCabecera";
            headerRow.SetValues(cabecera.ToArray(), 1);
            rows.Add(headerRow);
            rowIndex++;


            DataOrdenCompraDetalle detalleActual = null;

            for (int i = 0; i < datosDetalle.Count; i++)
            {
                detalleActual = datosDetalle[i];

                var row = new RowData(rowIndex);
                row.DefaultStyleId = "detalleDatos";
                row.Cells = hoja.MapperToCells(diccionario, rowIndex, detalleActual);
                rows.Add(row);
                rowIndex++;
            }

            return rows;
        }

        private List<RowData> GenerarDocumentoOrdenCompraPie(uint rowIndex, int colmunStart, DataOrdenCompra ordeCompra)
        {

            var diccionarioPie = new Dictionary<string, decimal>();
            diccionarioPie.Add("Total Bruto", ordeCompra.MontoSubTotal);
            diccionarioPie.Add("IGV (18%)", ordeCompra.MontoIgv);
            diccionarioPie.Add("Total", ordeCompra.MontoTotal);

            var rows = new List<RowData>();

            foreach (var datoCabecera in diccionarioPie)
            {
                var row = new RowData(rowIndex);

                var cells = new List<CellData>();
                var cell = new CellData();

                cell = new CellData(colmunStart + 2, rowIndex);
                cell.Value = datoCabecera.Key;
                cell.DataType = "System.String";
                cells.Add(cell);

                cell = new CellData(colmunStart + 3, rowIndex);
                cell.Value = datoCabecera.Value.ToString();
                cell.DataType = "System.Decimal";
                cells.Add(cell);

                row.Cells = cells;
                rows.Add(row);

                rowIndex++;
            }

            return rows;
        }

        #endregion

        #region Comprobante Pago
        public ProcessResult<List<DataComprobantePago>> BuscarComprobantePago(FiltroComprobantePago filtro)
        {
            ProcessResult<List<DataComprobantePago>> resultado = new ProcessResult<List<DataComprobantePago>>();
            try
            {
                var fechaInicio = Formato.StringFormatDatetime(filtro.FechaInicio);
                var fechaFin = Formato.StringFormatDatetime(filtro.FechaFin);

                var listado = comprobantePagoRepository.Buscar(codigoProveedor: filtro.CodigoProveedor, codigoEstado: filtro.CodigoEstado
                    , nombreProveedor: filtro.NombreProveedor, numeroComprobantePago: filtro.NumeroComprobantePago
                    , fechaInicio: fechaInicio, fechaFin: fechaFin);

                resultado.Result = listado.Select(x => new DataComprobantePago
                {
                    CodigoComprobantePago = x.CodigoComprobantePago,
                    CodigoOrdenCompra = x.CodigoOrdenCompra,

                    TipoComprobanteOrden = x.TipoComprobanteOrden,
                    NumeroComprobanteApagar = x.NumeroComprobanteApagar,
                    CodigoMoneda = x.CodigoMoneda,
                    CodigoProveedor = x.CodigoProveedor,
                    NombreProveedor = x.NombreProveedor,
                    AdelantoCuotas = x.AdelantoCuotas,
                    NumeroCuotaActual = x.NumeroCuotaActual,
                    NumeroCuotas = x.NumeroCuotas,
                    MontoComprobante = x.MontoComprobante,
                    FechaPago = Formato.DatetimeFormatString(x.FechaPago),
                    FechaProgramada = Formato.DatetimeFormatString(x.FechaProgramada),
                    Observaciones = x.Observaciones,
                    CodigoEstado = x.CodigoEstado,
                    NombreEstado = x.NombreEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion)

                }).ToList();
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataComprobantePago> ObtenerComprobantePago(int codigo)
        {
            ProcessResult<DataComprobantePago> resultado = new ProcessResult<DataComprobantePago>();
            try
            {
                var listado = comprobantePagoRepository.Buscar(codigoComprobantePago: codigo);
                var comprobantePago = listado.Select(x => new DataComprobantePago
                {
                    CodigoComprobantePago = x.CodigoComprobantePago,
                    CodigoOrdenCompra = x.CodigoOrdenCompra,

                    TipoComprobanteOrden = x.TipoComprobanteOrden,
                    NumeroComprobanteApagar = x.NumeroComprobanteApagar,
                    CodigoMoneda = x.CodigoMoneda,
                    CodigoProveedor = x.CodigoProveedor,
                    NombreProveedor = x.NombreProveedor,
                    AdelantoCuotas = x.AdelantoCuotas,
                    NumeroCuotaActual = x.NumeroCuotaActual,
                    NumeroCuotas = x.NumeroCuotas,
                    MontoComprobante = x.MontoComprobante,
                    FechaPago = Formato.DatetimeFormatString(x.FechaPago),
                    FechaProgramada = Formato.DatetimeFormatString(x.FechaProgramada),
                    Observaciones = x.Observaciones,
                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion)
                }).FirstOrDefault();


                resultado.Result = comprobantePago;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataComprobantePago> RegistrarComprobantePago(DataComprobantePago comprobantePago)
        {
            ProcessResult<DataComprobantePago> resultado = new ProcessResult<DataComprobantePago>();
            try
            {
                var comprobanteRegistro = new ComprobantePagoEntity();
                comprobanteRegistro.CodigoComprobantePago = comprobantePago.CodigoComprobantePago;
                comprobanteRegistro.CodigoOrdenCompra = comprobantePago.CodigoOrdenCompra;
                comprobanteRegistro.TipoComprobanteOrden = comprobantePago.TipoComprobanteOrden;
                comprobanteRegistro.NumeroComprobanteApagar = comprobantePago.NumeroComprobanteApagar;
                comprobanteRegistro.CodigoMoneda = comprobantePago.CodigoMoneda;
                comprobanteRegistro.CodigoProveedor = comprobantePago.CodigoProveedor;
                comprobanteRegistro.NombreProveedor = comprobantePago.NombreProveedor;
                comprobanteRegistro.AdelantoCuotas = comprobantePago.AdelantoCuotas;
                comprobanteRegistro.NumeroCuotas = comprobantePago.NumeroCuotas;
                comprobanteRegistro.NumeroCuotaActual = comprobantePago.NumeroCuotaActual;
                comprobanteRegistro.MontoComprobante = comprobantePago.MontoComprobante;
                comprobanteRegistro.FechaPago = Formato.StringFormatDatetime(comprobantePago.FechaPago).Value;
                comprobanteRegistro.FechaProgramada = Formato.StringFormatDatetime(comprobantePago.FechaProgramada).Value;
                comprobanteRegistro.Observaciones = comprobantePago.Observaciones;
                comprobanteRegistro.UsuarioCreacion = comprobantePago.UsuarioCreacion;
                comprobanteRegistro.UsuarioModificacion = comprobantePago.UsuarioModificacion;

                comprobanteRegistro.CodigoEstado = DatosConstantes.EstadoComprobantePago.Registrado;
                if (comprobanteRegistro.CodigoComprobantePago == 0)
                {                    
                    comprobantePago.CodigoComprobantePago = comprobantePagoRepository.Insertar(comprobanteRegistro);
                }
                else
                {
                    comprobantePagoRepository.Modificar(comprobanteRegistro);
                }

                resultado.Result = ObtenerComprobantePago(comprobantePago.CodigoOrdenCompra).Result;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<int>> ModificarEstadoComprobantePago(List<int> codigos, string estado, string usuario)
        {
            ProcessResult<List<int>> resultado = new ProcessResult<List<int>>();
            try
            {
                var listado = comprobantePagoRepository.ModificarEstado(codigos, estado, usuario);
                resultado.Result = codigos;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<byte[]> GenerarDocumentoComprobantePago(int codigo)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region Gasto Personal Proyecto
        public ProcessResult<List<DataGastoPersonalProyecto>> BuscarGastoPersonalProyecto(FiltroGastoPersonalProyecto filtro)
        {
            ProcessResult<List<DataGastoPersonalProyecto>> resultado = new ProcessResult<List<DataGastoPersonalProyecto>>();
            try
            {
                var fechaInicio = Formato.StringFormatDatetime(filtro.FechaInicio);
                var fechaFin = Formato.StringFormatDatetime(filtro.FechaFin);

                var listado = gastoPersonalProyectoRepository.Buscar(codigoProyecto: filtro.CodigoProyecto, codigoEstado: filtro.CodigoEstado
                    , nombreProyecto: filtro.NombreProyecto, fechaInicio: fechaInicio, fechaFin: fechaFin, codigoTipo: filtro.CodigoTipo);

                resultado.Result = listado.Select(x => new DataGastoPersonalProyecto
                {
                    CodigoGastoPersonal = x.CodigoGastoPersonal,
                    CodigoProyecto = x.CodigoProyecto,
                    NombreProyecto = x.NombreProyecto,
                    TipoGasto = x.TipoGasto,
                    MontoGasto = x.MontoGasto,
                    FechaGasto = Formato.DatetimeFormatString(x.FechaGasto),
                    Observaciones = x.Observaciones,
                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion),
                    DescripcionEstado = x.DescripcionEstado,
                    DescripcionTipo = x.DescripcionTipo
                }).ToList();
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataGastoPersonalProyecto> ObtenerGastoPersonalProyecto(int codigo)
        {
            ProcessResult<DataGastoPersonalProyecto> resultado = new ProcessResult<DataGastoPersonalProyecto>();
            try
            {
                var listado = gastoPersonalProyectoRepository.Buscar(codigoGastoPersonalProyecto: codigo);

                var gastoPersonal = listado.Select(x => new DataGastoPersonalProyecto
                {
                    CodigoGastoPersonal = x.CodigoGastoPersonal,
                    CodigoProyecto = x.CodigoProyecto,
                    NombreProyecto = x.NombreProyecto,
                    TipoGasto = x.TipoGasto,
                    MontoGasto = x.MontoGasto,
                    FechaGasto = Formato.DatetimeFormatString(x.FechaGasto),
                    Observaciones = x.Observaciones,
                    CodigoEstado = x.CodigoEstado,
                    UsuarioCreacion = x.UsuarioCreacion,
                    FechaCreacion = Formato.DatetimeFormatString(x.FechaCreacion),
                    UsuarioModificacion = x.UsuarioModificacion,
                    FechaModificacion = Formato.DatetimeFormatString(x.FechaModificacion)
                }).FirstOrDefault();


                resultado.Result = gastoPersonal;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<DataGastoPersonalProyecto> RegistrarGastoPersonalProyecto(DataGastoPersonalProyecto gastoPersonalProyecto)
        {
            ProcessResult<DataGastoPersonalProyecto> resultado = new ProcessResult<DataGastoPersonalProyecto>();
            try
            {
                var gastoRegistro = new GastoPersonalProyectoEntity();
                gastoRegistro.CodigoGastoPersonal = gastoPersonalProyecto.CodigoGastoPersonal;

                gastoRegistro.CodigoGastoPersonal = gastoPersonalProyecto.CodigoGastoPersonal;
                gastoRegistro.CodigoProyecto = gastoPersonalProyecto.CodigoProyecto;
                gastoRegistro.NombreProyecto = gastoPersonalProyecto.NombreProyecto;
                gastoRegistro.TipoGasto = gastoPersonalProyecto.TipoGasto;
                gastoRegistro.MontoGasto = gastoPersonalProyecto.MontoGasto;
                gastoRegistro.Observaciones = gastoPersonalProyecto.Observaciones;
                gastoRegistro.FechaGasto = Formato.StringFormatDatetime(gastoPersonalProyecto.FechaGasto).Value;
                gastoRegistro.Observaciones = gastoPersonalProyecto.Observaciones;
                gastoRegistro.UsuarioCreacion = gastoPersonalProyecto.UsuarioCreacion;
                gastoRegistro.UsuarioModificacion = gastoPersonalProyecto.UsuarioModificacion;

                if (gastoRegistro.CodigoGastoPersonal == 0)
                {
                    gastoRegistro.CodigoEstado = DatosConstantes.EstadoGastoPersonalProyecto.Registrado;
                    gastoPersonalProyecto.CodigoGastoPersonal = gastoPersonalProyectoRepository.Insertar(gastoRegistro);
                }
                else
                {
                    gastoPersonalProyectoRepository.Modificar(gastoRegistro);
                }

                resultado.Result = ObtenerGastoPersonalProyecto(gastoRegistro.CodigoGastoPersonal).Result;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<List<int>> ModificarEstadoGastoPersonalProyecto(List<int> codigos, string estado, string usuario)
        {
            ProcessResult<List<int>> resultado = new ProcessResult<List<int>>();
            try
            {
                var listado = gastoPersonalProyectoRepository.ModificarEstado(codigos, estado, usuario);
                resultado.Result = codigos;
            }
            catch (Exception e)
            {
                resultado.IsSuccess = false;
                resultado.Exception = new ApplicationLayerException<VentasService>(e);
            }

            return resultado;
        }

        public ProcessResult<byte[]> GenerarDocumentoGastoPersonalProyecto(int codigo)
        {
            throw new NotImplementedException();
        }
        #endregion

        public void Dispose()
        {

        }
    }
}
